package com.onec.service.trade.entity;

import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.onec.service.api.content.AesEntityContent;
import com.onec.service.api.dto.request.gateway.BizContent;
import com.onec.service.api.dto.response.customer.AgentInfoResp;
import com.onec.service.api.dto.response.customer.MerchantResp;
import com.onec.service.api.dto.response.route.RouteResp;
import com.onec.service.api.enums.ProductEnum;
import com.onec.service.api.enums.StatusEnum;
import com.onec.service.api.utils.StringMapUtil;
import lombok.Data;
import org.hibernate.annotations.ColumnTransformer;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

/**
 * 在线订单实体
 *
 * @author ONEC
 */
@Entity
@Table(name = "t_online_order")
@Data
public class OnlineOrder implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true)
    private Long id;

    @Column(name = "version", length = 8)
    private Integer version;

    /**
     * 代理商编号
     */
    @Column(name = "agent_id", length = 16)
    private Long agentId;
    /**
     * 商户编号
     */
    @Column(name = "merchant_id", length = 16)
    private Long merchantId;
    /**
     * 商户编号
     */
    @Column(name = "merchant_no", length = 32)
    private String merchantNo;

    /**
     * 通道上游编号
     */
    @Column(name = "channel_merchant_no", length = 32)
    private String channelMerchantNo;

    /**
     * 通道编号
     */
    @Column(name = "channel_no", length = 16)
    private String channelNo;

    /**
     * 通道编号
     */
    @Column(name = "channel_business_no", length = 16)
    private String channelBusinessNo;

    /**
     * 类型码编号
     */
    @Column(name = "business_no", length = 32)
    private String businessNo;

    /**
     * 下游订单号
     */
    @Column(name = "external_num", length = 32, unique = true)
    private String externalNum;

    /**
     * 上游订单号
     */
    @Column(name = "trade_num", length = 32, unique = true)
    private String tradeNum;

    /**
     * 平台流水号
     */
    @Column(name = "serial_num", length = 32, unique = true)
    private String serialNum;

    /**
     * 手续费：
     */
    @Column(name = "agent_rate_fee", length = 8, scale = 4)
    private BigDecimal agentRateFee;

    /**
     * 机构固定值：
     */
    @Column(name = "agent_fee", length = 8, scale = 4)
    private BigDecimal agentFee;


    /**
     * 商户手续费（固定值）
     */
    @Column(name = "merchant_rate_fee", length = 8, scale = 4)
    private BigDecimal merchantRateFee;


    /**
     * 商户手续费（固定值）
     */
    @Column(name = "merchant_fee", length = 8, scale = 4)
    private BigDecimal merchantFee;

    /**
     * 通道手续费（固定值）
     */
    @Column(name = "channel_fee", length = 8, scale = 1)
    private BigDecimal channelFee;

    /**
     * 商户固定手续费
     */
    @Column(name = "channel_rate_fee", length = 8, scale = 4)
    private BigDecimal channelRateFee;

    /**
     * 交易金额
     */
    @Column(name = "amount", length = 8, scale = 2)
    private BigDecimal amount;

    /**
     * 优惠金额
     */
    @Column(name = "coupon_amount", length = 8, scale = 2)
    private BigDecimal couponAmount;

    /**
     * 优惠信息：jsonobject
     */
    @Column(name = "coupon_list", length = 128)
    private String couponList;
    /**
     * 优惠信息：jsonobject
     */
    @Column(name = "product", length = 8)
    @Enumerated(EnumType.STRING)
    private ProductEnum product;

    /**
     * 创建时间
     */
    @Column(name = "create_time", length = 0)
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    @JsonFormat(pattern = "yyyy-MM-dd HH:ss:mm", timezone = "GTM+8")
    private Date createTime;

    /**
     * 完成时间
     */
    @Column(name = "complete_time", length = 0)
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:ss:mm", timezone = "GTM+8")
    private Date completeTime;

    /**
     * 完成时间
     */
    @Column(name = "update_time", length = 0)
    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:ss:mm", timezone = "GTM+8")
    private Date updateTime;

    /**
     * 通道完成时间
     */
    @Column(name = "channel_complete_time", length = 0)
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:ss:mm", timezone = "GTM+8")
    private Date channelCompleteTime;

    /**
     * 订单过期时间
     */
    @Column(name = "time_expire", length = 0, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:ss:mm", timezone = "GTM+8")
    private Date timeExpire;

    /**
     * 交易订单状态
     */
    @Column(name = "status", length = 12)
    @Enumerated(EnumType.STRING)
    private StatusEnum status;

    /**
     * 订单出款状态
     */
    @Column(name = "withdrew_status", length = 12)
    @Enumerated(EnumType.STRING)
    private StatusEnum withDrewStatus;

    /**
     * 交易卡号
     */
    @Column(name = "card_no")
    @ColumnTransformer(
            read = AesEntityContent.AES_DECRYPT_CARD_NO,
            write = AesEntityContent.AES_ENCRYPT_CARD_NO
    )
    private String cardNo;

    /**
     * 银行名称
     */
    @Column(name = "bank_name", length = 32)
    private String bankName;
    /**
     * 银行名称
     */
    @Column(name = "bank_code", length = 32)
    private String bankCode;

    /**
     * 交易手机号
     */
    @ColumnTransformer(
            read = AesEntityContent.AES_DECRYPT_PHONE,
            write = AesEntityContent.AES_ENCRYPT_PHONE
    )
    @Column(name = "phone")
    private String phone;

    /**
     * 产品备注
     */
    @Column(name = "remarks", length = 64)
    private String remarks;
    /**
     * 产品备注
     */
    @Column(name = "area_code", length = 8)
    private String areaCode;
    /**
     * 产品备注
     */
    @Column(name = "mcc", length = 8)
    private String mcc;


    public OnlineOrder() {
    }


    public OnlineOrder(MerchantResp merchantResp, AgentInfoResp agentResp, BizContent bizContent, RouteResp routeResp) {
        this.version = 0;
        this.agentId = merchantResp.getAgentId();
        this.merchantId = merchantResp.getId();
        this.merchantNo = merchantResp.getMerchantNo();
        this.channelMerchantNo = "";
        this.channelNo = routeResp.getChannelNo();
        this.channelBusinessNo = routeResp.getChannelBusinessNo();
        this.businessNo = merchantResp.getBusinessNo();
        this.externalNum = bizContent.getExternalNum();
        this.tradeNum = StringMapUtil.getStrByLength("IOC", 8);
        this.serialNum = StringMapUtil.getStrByLength("IO", 8);
        this.agentFee = agentResp.getFee();
        BigDecimal tradeAmount = new BigDecimal(bizContent.getAmount());
        this.agentRateFee = tradeAmount.multiply(agentResp.getRate()).setScale(2, RoundingMode.HALF_UP);
        this.merchantRateFee = tradeAmount.multiply(merchantResp.getFee()).setScale(2, RoundingMode.HALF_UP);
        this.channelRateFee = tradeAmount.multiply(routeResp.getRate()).setScale(2, RoundingMode.HALF_UP);
        this.channelFee = routeResp.getFee();
        this.amount = tradeAmount;
        this.couponAmount = new BigDecimal("0");
        this.couponList = "";
        this.product = ProductEnum.valueOf(merchantResp.getProduct());
        this.businessNo = merchantResp.getBusinessNo();
        this.createTime = DateUtil.date();
        this.completeTime = DateUtil.date();
        this.channelCompleteTime = DateUtil.date();
        this.timeExpire = DateUtil.offsetMinute(DateUtil.date(), 10);
        this.status = StatusEnum.INIT;
        this.withDrewStatus = StatusEnum.INIT;
        this.cardNo = bizContent.getCardNo();

        this.bankName = routeResp.getBankName();
        this.phone = bizContent.getPhone();
        this.remarks = "";

        this.areaCode = bizContent.getAreaCode();
        this.mcc = bizContent.getMcc();
    }


}
